﻿namespace NMortgage.UI.Tests.Model
{

    using Microsoft.VisualStudio.TestTools.UnitTesting;

    using NMortgage.UI.Model;

    [TestClass]
    public class ExtraPaymentTests : TestBase<ExtraPayment>
    {
        #region Methods

        public static ExtraPaymentCollection GetInvalidCollectionTarget()
        {
            var p = new ExtraPaymentCollection();
            p.Add(GetParameter0());
            p.Add(GetInvalidParameter0());

            return p;
        }

        public static ExtraPayment GetInvalidParameter0()
        {
            return new ExtraPayment() { Amount = 0, OffsetMonths = -10, OffsetYears = -110 };
        }

        public static ExtraPayment GetParameter0()
        {
            return new ExtraPayment() { Amount = 10, OffsetMonths = 10, OffsetYears = 10 };
        }

        public static ExtraPayment GetParameter1()
        {
            return new ExtraPayment() { Amount = 100, OffsetMonths = 1, OffsetYears = 10 };
        }

        public static ExtraPayment GetParameter2()
        {
            return new ExtraPayment() { Amount = 1000, OffsetMonths = 1, OffsetYears = 1 };
        }


        public static ExtraPayment GetInvalidParameter1()
        {
            return new ExtraPayment()
            {
                Amount = 1,
                OffsetMonths = 1,
                OffsetYears = 1,
                Frequency = 0,
                Years=0,
                Months=0,
                FrequencyMeasure = ExtraPaymentFrequency.Months,
                Type = ExtraPaymentType.Recurring
            };
        }

        public static ExtraPayment GetParameter3()
        {
            return new ExtraPayment() { Amount = 1000, OffsetMonths = 1, OffsetYears = 1, 
                Frequency = 1, FrequencyMeasure=ExtraPaymentFrequency.Months, Type=ExtraPaymentType.Recurring };
        }


        public static ExtraPaymentCollection GetValidCollectionTarget()
        {
            var p = new ExtraPaymentCollection();
            p = new ExtraPaymentCollection();
            p.Add(GetParameter0());
            p.Add(GetInvalidParameter0());

            return p;
        }

        [TestMethod]
        public void AmountTest()
        {
            double expected = 1d;
            double actual;
            Subject.Amount = expected;
            actual = Subject.Amount;
            Assert.AreEqual(expected, actual);
        }


        [TestMethod]
        public void Total_Duration_in_month_adds_properly()
        {
            int y = 1, m = 1;
            int expected = 12*y+m;
            int actual;
            Subject.Years = y;
            Subject.Months = m;
            actual = Subject.TotalDurationInMonths;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void Total_Offset_in_month_adds_properly()
        {
            int y = 1, m = 1;
            int expected = 12 * y + m;
            int actual;
            Subject.OffsetYears = y;
            Subject.OffsetMonths = m;
            actual = Subject.TotalOffsetInMonths;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ExtraPaymentCollectionValidator_Constructor()
        {
            var target = new ExtraPaymentCollectionValidator();
            Assert.IsNotNull(target);
        }

        [TestMethod]
        public void ExtraPaymentCollectionValidator_HaveValidChildrenTest()
        {
            var validationTarget = GetInvalidCollectionTarget();
            var subject = new ExtraPaymentCollectionValidator();
            bool expected = false;
            bool actual = subject.HaveValidChildren(validationTarget, 0);
            Assert.AreEqual(expected, actual);

            validationTarget.Clear();
            validationTarget.Add(GetParameter0());
            validationTarget.Add(GetParameter1());
            validationTarget.Add(GetParameter2());

            expected = true;
            actual = subject.HaveValidChildren(validationTarget, 0);
            Assert.AreEqual(expected, actual);

            validationTarget.Add(GetInvalidParameter0());
            expected = false;
            actual = subject.HaveValidChildren(validationTarget, 0);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ExtraPaymentCollection_Constructor()
        {
            var target = new ExtraPaymentCollection();
            Assert.IsNotNull(target);
        }

        [TestMethod]
        public void ExtraPaymentValidator_Constructor()
        {
            var target = new ExtraPaymentValidator();
            Assert.IsNotNull(target);
        }

        //[TestMethod]
        //public void ExtraPaymentValidator_HaveYearsMonthsGreaterThanZero()
        //{
        //    bool expected = true;
        //    bool actual;

        //    var validator = new ExtraPaymentValidator_Accessor();

        //    Subject.Years = 0;
        //    Subject.Months = 1;
        //    actual = validator.HaveYearsMonthsGreaterThanZero(Subject, 0);
        //    Assert.AreEqual(expected, actual);

        //    Subject.Years = 1;
        //    Subject.Months = 1;
        //    actual = validator.HaveYearsMonthsGreaterThanZero(Subject, 0);
        //    Assert.AreEqual(expected, actual);

        //    Subject.Years = 1;
        //    Subject.Months = 0;
        //    actual = validator.HaveYearsMonthsGreaterThanZero(Subject, 0);
        //    Assert.AreEqual(expected, actual);
        //}

        [TestMethod]
        public void ExtraPayment_Constructor()
        {
            var target = new ExtraPayment();
            Assert.IsNotNull(target);
        }

        [TestMethod]
        public void ExtraPayment_Description_NotNull()
        {
            Subject.Amount = 1d;
            Subject.OffsetMonths = 1;
            Subject.Type = ExtraPaymentType.OneTime;

            string actual = Subject.Description;
            Assert.IsFalse(string.IsNullOrEmpty(actual));

            Subject.Type = ExtraPaymentType.Recurring;

            actual = Subject.Description;
            Assert.IsFalse(string.IsNullOrEmpty(actual));
        }

        [TestMethod]
        public void MonthsTest()
        {
            int expected = 1;
            int actual;
            Subject.Months = expected;
            actual = Subject.Months;
            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void OffsetMonthsTest()
        {
            int expected = 1;
            int actual;
            Subject.OffsetMonths = expected;
            actual = Subject.OffsetMonths;
            Assert.AreEqual<int>(expected, actual);
        }

        [TestInitialize]
        public void TestInitialize()
        {
            Subject = new ExtraPayment();
        }

        [TestMethod]
        public void YearsTest()
        {
            int expected = 1;
            int actual;
            Subject.Years = expected;
            actual = Subject.Years;
            Assert.AreEqual<int>(expected, actual);
        }


        [TestMethod]
        public void FrequencyTest()
        {
            int expected = 1;
            int actual;
            Subject.Frequency = expected;
            actual = Subject.Frequency;
            Assert.AreEqual<int>(expected, actual);
        }

        [TestMethod]
        public void FrequencyMeasureTest()
        {
            var expected = ExtraPaymentFrequency.Months;
            Subject.FrequencyMeasure = expected;
            var actual = Subject.FrequencyMeasure;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void OffSetYearsTest()
        {
            int expected = 1;
            int actual;
            Subject.OffsetYears = expected;
            actual = Subject.OffsetYears;
            Assert.AreEqual<int>(expected, actual);
        }

        #endregion Methods
    }
}